﻿//#include <iostream>
//#include <vector>  
//#include <algorithm>
//using namespace std;
//struct Goods
//{
//    string _name;  // 名字
//    double _price; // 价格
//    int _evaluate; // 评价
//    Goods(const char* str, double price, int evaluate)
//        :_name(str)
//        , _price(price)
//        , _evaluate(evaluate)
//    {}
//};
//struct ComparePriceLess //仿函数
//{
//    bool operator()(const Goods& gl, const Goods& gr)
//    {
//        return gl._price < gr._price;
//    }
//};
//struct ComparePriceGreater //仿函数
//{
//    bool operator()(const Goods& gl, const Goods& gr)
//    {
//        return gl._price > gr._price;
//    }
//};
//int main()
//{
//    vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2,
//   3 }, { "菠萝", 1.5, 4 } };
//    //下面两个排序需要编写两个访函数
//    sort(v.begin(), v.end(), ComparePriceLess()); //按价格从小到大排序
//    sort(v.begin(), v.end(), ComparePriceGreater()); //按价格从大到小排序
//    //下面两个排序使用lambda匿名函数，可看出要比伪函数或函数指针更简便
//    sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {return g1._price < g2._price; });
//    sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {return g1._price > g2._price; });
//    //上面[](const Goods& g1, const Goods& g2) {return g1._price < g2._price; }会自动推导函数提返回类型是bool,
//    //即与[](const Goods& g1, const Goods& g2)->bool {return g1._price < g2._price; }等效
//    return 0;
//}

//#include <iostream>
//using namespace std;
//int main()
//{
//	int x = 10;
//	//使用lambda函数捕获x的引用并修改它  
//	auto m = [&x]() {x = x * x; }; //m是一个实现访函数的类
//	m(); //lambda函数的调用 
//	cout << "x: " << x << endl;
//	cout << typeid(m).name() << endl;
//	return 0;
//}

//class A
//{
//public:
//	int operator()(int x)
//	{
//		return 55 + 51;
//	}
//};
//int main()
//{
//	//调用错误，lambda函数的返回值是int，但本身返回值不是int，是一个类类型
//	int a = [](int x)->int {return 55 + 5l; };
//	//auto自动推演类型，调用正确
//	auto _a = [](int x)->int {return 55 + 5l; };
//	//赋予lambda函数表达式名称为_a，而lambda底层是类的访函数，按照仿函数的调用即可
//	int b = _a(5);
//
//	A _a;
//	int b = _a(5);
//	//[](int x)->int {return 55 + 5l; }; 的调用相当于int x; A()(x); 的调用
//	return 0;
//}

//#include <iostream>
//using namespace std;
//int main()
//{
//	int a = 10, b = 10;
//	//值传递捕捉a，捕捉的是a的拷贝
//	auto fun1 = [a, b]()mutable { a += 1; b += 1; return a + b; }; //lambda默认是const函数，限制了捕捉列表的参数，这里要使用mutable取消对捕捉列表的限制
//	cout << "fun1: a + b = " << fun1() << endl;
//	cout << "a + b = " << a + b << endl;
//	cout << endl;
//	//引用传递捕捉b，捕捉的是b的引用
//	auto fun2 = [&a, &b] {a += 1; b += 1; return a + b; }; //捕捉列表引用捕捉，说明开发者想要对其修改，lambda没有对捕捉列表限制，可以修改
//	cout << "fun2: a + b = " << fun2() << endl;
//	cout << "a + b = " << a + b << endl;
//	cout << endl;
//	//值传递获取当前作用域所有变量，捕捉所有变量的拷贝
//	int c = 10, d = 10;
//	auto fun3 = [=]()mutable {c += 1; d += 1; return c + d; }; //与上面“值传递捕捉a”同理
//	cout << "fun3: c + d = " << fun3() << endl;
//	cout << "c + d = " << c + d << endl;
//	cout << endl;
//	//引用传递获取当前作用域所有变量，捕捉所有变量的引用
//	auto fun4 = [&] {c += 1; d += 1; return c + d; }; //与上面“引用传递捕捉b”同理
//	cout << "fun4: c + d = " << fun4() << endl;
//	cout << "c + d = " << c + d << endl;
//	cout << endl;
//	//捕捉a的拷贝，其它数据的引用
//	auto fun5 = [&, a]()mutable {a = 1; b = 1; c = 1; return a + b + c; };
//	//auto fun6 = [=, &a]()mutable {a = 1; b = 1; c = 1; return a + b + c; };这里也可捕捉a的引用，其它数据的拷贝
//	cout << "fun5: a + b + c = " << fun5() << endl;
//	cout << "a + b + c = " << a + b + c;
//	cout << endl;
//	return 0;
//}

//#include <iostream>
//using namespace std;
//void (*PF)();
//int main()
//{
//	auto a = [] {cout << "Hello C++" << endl; };
//	auto b = [] {cout << "Hello C++" << endl; };
//
//	//a = b; //编译失败，lambda实现虽都一样，但两者的类型不一样，内部不存在不同类型间的赋值。从下面的输出可看出
//	cout << typeid(a).name() << endl;
//	cout << typeid(b).name() << endl;
//	cout << endl;
//	//允许使用一个lambda表达式拷贝构造一个新的副本。两者的类型相同。
//	auto c(a);
//	cout << typeid(c).name() << endl;
//	cout << typeid(a).name() << endl;
//	cout << endl;
//	c();
//	//也可以将lambda表达式赋值给相同类型的函数指针
//	PF = a;
//	PF();
//	return 0;
//}

//class Rate
//{
//public:
//	Rate(double rate) : _rate(rate)
//	{}
//	double operator()(double money, int year)
//	{
//		return money * _rate * year;
//	}
//private:
//	double _rate;
//};
//int main()
//{
//	//函数对象
//	double rate = 0.49;
//	Rate r1(rate);
//	r1(10000, 2);
//	//lamber表达式
//	auto r2 = [=](double monty, int year)->double {return monty * rate * year; };
//	r2(10000, 2);
//	return 0;
//}